/**
 *
 * @file : http_server.h
 *
 * @brief : HTTP SERVER header
 *
 * $Id: $
 */

/*
 * This file is part of Tsar.
 *
 * Tsar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tsar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tsar.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

#include "utils.h"

/** @def Web directory where there is the report */
#define WEB_DIRECTORY "web"

/** @def Min size expected in http header */
#define MIN_HTTP_EXPECTED_SIZE  10

/** @def Error code, the request doesn't even look like a valid one */
#define BAD_REQUEST             0x00
/** @def If we are using GET method */
#define HTTP_METHOD_GET         0x01
/** @def If we are using POST method */
#define HTTP_METHOD_POST        0x02
/** @def Error code, the METHOD used is not supported */
#define HTTP_METHOD_INVALID     0x03


/* This struct contain all needed params for the http server*/

/** @brief Http item, it travels all over http functions */
typedef struct  {
    /** @brief Http header client request  */
    char * clientRequest;
    /** @brief Http header server response  */
    char * serverResponse;
    /** @brief requested file  */
    char * requestedFile;    
    /** @brief Http header + file  */
    char * entireResponse;
    
    /** @brief size of server header */
    unsigned long headerSize;
    /** @brief size of sent file */
    unsigned long contentLength;
    /** @brief size of server header + sent file  */
    unsigned long replyLen;

    /** @brief METHOD in Http header client request  */
    char * method;
    /** @brief PATH specified in Http header client request  */
    char * path;
    /** @brief PROTOCOL used for Http header client request  */
    char * protocol;

    /** @brief Is true if requested file is existing and authorized */
    bool_t isAuthorized;

    /** @brief Number of returned status code  */
    unsigned int numberCode;
    /** @brief Text of return status */
    char * returnCode;

    /** @brief file requested mimeType  */
    char * mimeType;
    /** @brief Line of param dropped in POST  */
    char * paramLine;
} http_t ;

/** @brief Http status item, using the number of the status code and the text that it corresponds to ( ex: 200 OK ) */
typedef struct {
	/** @brief Status code  */
     int numberCode;
	/** @brief Description of status code */
     char * textCode;
} httpStatus_t;

/* -- F U N C T I O N S  P R O T O T Y P E S -- */

/* External fonctions */

/**
 * @brief Init http handler, receipt it, and craft a response and send the handler
 * @return a malloc()ed handle to the opened http session
 * @retval NULL on error
 */
http_t* http_server_reply( char* httpHeader, ssize_t len, char * pcapFilename );

/**
 * @brief Destroy http handler
 * @return void
 */
void http_destroy_handle( http_t* httpHandler );

/* Internal fonctions */

/**
 * @brief Init http handler and return it
 * @return a malloc()ed handle to the opened http session
 * @retval NULL on error
 */
http_t* init_http_handler (void);

/**
 * @brief check header size, method path and protocol, and set status code.
 * @param httpHeader client Header
 * @param clientHeaderSize header client size
 * @param httpHandler httpHandler pointer
 * @return int variable
 * @retval 0 if ok
 * @retval 1 if client header too short
 */
int receipt_http_header( char * httpHeader, ssize_t clientHeaderSize, http_t* httpHandler );

/**
 * @brief check path and rewrite it if the file doesn't exist or is not authorized
 * @param httpHandler httpHandler pointer
 */
void check_path ( http_t* httpHandler );

/**
 * @brief get method path and protocol from client header
 * @param httpHeader client Header
 * @param httpHandler httpHandler pointer
 * @return Method used
 */
int get_method_path_protocol( char * httpHeader, http_t * httpHandler );

/**
 * @brief Build server response : server header and file requested
 * @param pcapFilename pcapFilename using to create report
 * @param httpHandler httpHandler pointer
 * @return 0 if OK
 */
int craft_reply_header ( http_t* httpValues, char * pcapFilename );

/**
 * @brief Assemblate the header and file in one buffer
 * @param httpHandler httpHandler pointer
 */
void finalize_http_reply( http_t* httpHandler );

/**
 * @brief Search paramLine when the client header is using POST method
 * @param httpHandler httpHandler pointer
 */
void do_POST_reply ( http_t* httpHandler );

/**
 * @brief Just a debug when client header use GET method
 * @param httpHandler httpHandler pointer
 */
void do_GET_reply ( http_t* httpHandler );

/**
 * @brief get param value POSTED by user
 * @param headerLine client Header Line 
 * @param httpHandler httpHandler pointer
 */
void give_params_value ( char* headerLine, http_t* httpHandler );

/**
 * @brief get mime type of requested file
 * @param httpHandler httpHandler pointer
 */
void get_mime_type ( http_t* httpHandler );

/**
 * @brief load file in buffer, and put fileSize in the fileLen ptr
 * @param filename Name of requested file 
 * @param fileLen size of file
 * @return buffer where file is loaded
 */
unsigned char * load_file( char * filename, unsigned long * fileLen );

/**
 * @brief load error file and build error page
 * @param errorType Type of error is used to change error page aspect
 */
int load_error( int errorType );

/**
 * @brief set description in the httpHandler associated to the status code
 * @param httpHandler httpHandler pointer
 * @param  code status code
 */
void set_status_code( http_t* httpHandler, int code );

/**
 * @brief return description associated to the status code
 * @param  code status code
 */
char * str_status_code( int code );

/**
 * @brief secure path 
 * @param httpHandler httpHandler pointer
 */
void secure_path ( http_t * httpHandler );

/**
 * @brief working like fopen but openning files in the web directory ( ex : index.html->webdir/index.html )
 * @param path used in fopen(path,)
 * @param  mod mod used in fopen(,mod)
 * @return File ptr
 */
FILE * Fopen_HTTP ( char * path, char * mod );

/**
 * @brief Unescape string ( ex : "a+b%27+c" ==> "a b' c" )
 * @param encoded encoded string
 * @return decoded string
 */
char * url_decode( char * encoded );

/**
 * @brief transform hex to dec 
 * @param byte hex
 * @return dec associated to hex params
 */
char hex2dec_char( char * bytes );

/**
 * @brief Delete "mov" first chars
 * @param str string to modifie
 * @param  mov chars to destroy
 */
void rotate_string_left( char * str, unsigned int mov );


#endif /* HTTP_SERVER_H */

